﻿using System;
using System.IO;
using SevenZip;

namespace ExtensionHelper.Zip
{
    /// <summary>
    /// 压缩类
    /// </summary>
    public class ZipHelper
    {
        private static string libPath = Environment.CurrentDirectory + @"\7z64.dll";

        /// <summary>
        /// 将压缩包拆分
        /// </summary>
        /// <param name="file">要拆分的压缩包</param>
        /// <param name="folder">拆分后的压缩包文件夹路径</param>
        /// <param name="size"></param>
        /// <returns></returns>
        public static bool SplitZip(string file, string folder, int size)
        {
            //如果压缩包和拆分后的文件夹处于同一目录，则不处理
            if (!Directory.GetParent(file).FullName.Equals(new DirectoryInfo(folder).FullName))
            {
                if (Directory.Exists(folder))
                {
                    Directory.Delete(folder, true);
                }
                Directory.CreateDirectory(folder);
            }
            if (!File.Exists(file))
            {
                return false;
            }

            BinaryReader inReader = null;
            try
            {
                inReader = new BinaryReader(File.OpenRead(file));

                for (var num = 1; ; num++)
                {
                    var buffer = inReader.ReadBytes(size);
                    if (buffer.Length > 0)
                    {
                        using (var outStream = File.Create(string.Format("{0}\\{1}.zip", folder, num.ToString("D4"))))
                        {
                            outStream.Write(buffer, 0, buffer.Length);
                            outStream.Flush();
                        }
                    }
                    if (buffer.Length < size)
                    {
                        break;
                    }
                }
            }
            catch
            {
                return false;
            }
            finally
            {
                if (inReader != null)
                {
                    inReader.Close();
                }
                File.Delete(file);
            }
            return true;
        }

        /// <summary>
        /// 将压缩包合并
        /// </summary>
        /// <param name="folder">要合并的压缩包文件夹路径</param>
        /// <param name="filePath">要合并的压缩包</param>
        /// <returns></returns>
        public static bool MergeZip(string folderPath, string filePath)
        {
            //如果压缩包和要合并的文件夹处于同一目录，则不处理
            if (!Directory.GetParent(filePath).ToString().Equals(folderPath))
            {
                if (Directory.Exists(folderPath))
                {
                    Directory.Delete(folderPath, true);
                }
                Directory.CreateDirectory(folderPath);
            }
            if (!Directory.Exists(folderPath))
            {
                return false;
            }
            if (File.Exists(filePath))
            {
                File.Delete(filePath);
            }

            BinaryWriter bw = null;
            try
            {
                string[] files = Directory.GetFiles(folderPath, "*.zip");
                bw = new BinaryWriter(new FileStream(filePath, FileMode.Create));
                foreach (string file in files)
                {
                    //循环压缩包，写入到合并压缩包中
                    using (FileStream fs = new FileStream(string.Format(@"{0}\{1}", folderPath, Path.GetFileName(file)), FileMode.Open))
                    {
                        using (BinaryReader br = new BinaryReader(fs))
                        {
                            bw.Write(br.ReadBytes((int)fs.Length));
                        }
                    }
                }
            }
            catch
            {
                return false;
            }
            finally
            {
                if (bw != null)
                {
                    bw.Close();
                }
            }
            return true;
        }

        /// <summary>
        /// 7z压缩(支持x64)
        /// </summary>
        /// <param name="folderPath"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static bool Zip(string folderPath, string filePath)
        {
            try
            {
                SevenZipCompressor.SetLibraryPath(libPath);
                SevenZipCompressor cmp = new SevenZipCompressor();
                cmp.ArchiveFormat = OutArchiveFormat.SevenZip;
                cmp.CompressionLevel = CompressionLevel.Normal;
                cmp.CompressionMethod = SevenZip.CompressionMethod.Default;
                cmp.VolumeSize = 0;
                cmp.CompressDirectory(folderPath, filePath);
                return true;
            }
            catch { return false; }
        }
        
        /// <summary>
        /// 7z解压(支持x64)
        /// </summary>
        /// <param name="folderPath"></param>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static bool UnZip(string folderPath, string filePath)
        {
            try
            {
                SevenZipExtractor.SetLibraryPath(libPath);
                var extr = new SevenZipExtractor(filePath);
                extr.ExtractArchive(folderPath);
                return true;
            }
            catch { return false; }
        }
    }
}
